/*
 * This file is part of Sparwe.
 *
 *  Sparwe is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Sparwe is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Sparwe.  If not, see <http://www.gnu.org/licenses/>.
 */ 


#ifndef __DEVICE_H__
#define __DEVICE_H__

#include <vector>
#include <string>
#include <SFML/Window.hpp>

namespace sp_core
{
	/** 
	 * @brief Holds information of the window settings.
	 */
	class WindowSettings
	{
		public:
			
		
			/** 
			 * @brief 
			 * 
			 * @return 
			 */
			int GetWidth() const { return mWidth; }

			/** 
			 * @brief 
			 * 
			 * @return 
			 */
			int GetHeight() const { return mHeight; }

			/** 
			 * @brief 
			 * 
			 * @return 
			 */
			int GetBitsPerPixel() const { return mBitsPerPixel; }

			/** 
			 * @brief 
			 * 
			 * @return 
			 */
			int GetXPosition() const { return mXPosition; }
			
			/** 
			 * @brief 
			 * 
			 * @return 
			 */
			int GetYPosition() const { return mYPosition; }

			/** 
			 * @brief 
			 * 
			 * @return 
			 */
			bool IsFullscreen() const { return mFullscreen; }

			/** 
			 * @brief 
			 * 
			 * @param width 
			 */
			void SetWidth(int width) { mWidth = width; }
			
			/** 
			 * @brief 
			 * 
			 * @param height 
			 */
			void SetHeight(int height) { mHeight = height; }
			
			/** 
			 * @brief 
			 * 
			 * @param bitsPerPixel 
			 */
			void SetBitsPerPixel(int bitsPerPixel) { mBitsPerPixel = bitsPerPixel; }

			/** 
			 * @brief 
			 * 
			 * @param position 
			 */
			void SetXPosition(int position) { mXPosition = position; }
			
			/** 
			 * @brief 
			 * 
			 * @param position 
			 */
			void SetYPosition(int position) { mYPosition = position; }

			/** 
			 * @brief 
			 * 
			 * @param setFullscreen 
			 */
			void SetFullscreen(bool setFullscreen) { mFullscreen = setFullscreen; }
			

		private:

			int mWidth;
			int mHeight;
			int mBitsPerPixel;

			int mXPosition;
			int mYPosition;

			bool mFullscreen;
	};

	/** 
	 * @brief Contains the device settings, windows settings, hardware settings etc.
	 */
	class DeviceSettings
	{
		public:


			WindowSettings mWindow;

	};

	class Driver;
	class EventManager;
	class Event;

	/** 
	 * @brief The Device keeps track of the graphics device and displays the window.
	 */
	class Device
	{
		public:
			/** 
			 * @brief 
			 * 
			 * @param settings 
			 */
			Device(DeviceSettings* settings);

			/** 
			 * @brief 
			 */
			~Device();
			
			/** 
			 * @brief Returns the running version of the engine.
			 * 
			 * @return Version
			 */
			char GetVersion() const;

			/** 
			 * @brief Do not use yet!
			 * 
			 * @param cap 
			 */
			void EnableMode(GLenum cap) const;

			/** 
			 * @brief Do not use yet!
			 * 
			 * @param cap 
			 */
			void DisableMode(GLenum cap) const;
			
			/** 
			 * @brief Changes the window mode to fullscreen i mode is true, windowed if false.
			 * 
			 * @param mode true: fullscreen, false: windowed
			 * 
			 * @return True if the mode change was successful
			 */
			bool SetFullscreen(bool mode);

			/** 
			 * @brief Provides the graphic card capabilities.
			 * Returns a vector with strings, each defining a capability of the current graphics card.
			 * 
			 * @return The capabilities...
			 */
			std::vector<std::string> GetCapabilities() const;
			
			/** 
			 * @brief Creates the engine driver.
			 * Creates the engine driver which is used for rendering, scene management(partly) and 
			 * lots of more funky stuff!
			 * 
			 * @return A pointer to a driver.
			 */
			Driver* CreateDriver(); 			

			/** 
			 * @brief Displays the window.
			 * Displays the window, this must be done each frame!
			 *
			 */
			void Display();

			
			/** 
			 * @brief Updates the window.
			 * This method redraws the window and sends events to the internal event queue.
			 *
			 */
			void Update();

			/** 
			 * @brief Creates a device from the config file.
			 * 
			 * @param filename Path to the config file.
			 * 
			 * @return A configured device.
			 */
			static Device* CreateDevice(std::string filename);


			/** 
			 * @brief Returns the window handle.
			 * 
			 * @return window handle.
			 */
			sf::Window* GetWindowHandle()
			{ 
				return &mWindow;
			}



		private:

			/** 
			 * @brief Creates the event manager...
			 */
			void CreateEventManager();

			EventManager *mEvents;

			DeviceSettings* mpSettings;
			sf::Window mWindow;

	};


}



#endif
